package com.liu.es.test;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Test;

import java.io.IOException;

public class ES高级查询 {
    static RestHighLevelClient rest = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));


    public static void main(String[] args) throws IOException {
        //创建搜索对象
        SearchRequest search = new SearchRequest();
        //指定搜索的索引
        search.indices("user");
        //构建查询体
        SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
        /**
         *
         * 这里做查询全部
         //查询所有数据
         searchBuilder.query(QueryBuilders.matchAllQuery());
         **/

        //term查询关键字
//        searchBuilder.query(QueryBuilders.termQuery("name","zhangsan"));

        //分页
//        searchBuilder.query(QueryBuilders.matchAllQuery());
//        searchBuilder.size(2);
//        searchBuilder.from(1);

        //排序    ASC:升序      DESC:降序
//        searchBuilder.sort("age", SortOrder.ASC);

        //过滤字段
//        String[] excludes = {};
//        String[] includes = {"name","age"};
//        searchBuilder.fetchSource(includes,excludes);

        //bool查询
        //先创建bool的请求体对象
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.must(QueryBuilders.matchQuery("age","3"));
//        boolQueryBuilder.must(QueryBuilders.matchQuery("name","zhaoliu"));
//        boolQueryBuilder.should(QueryBuilders.matchQuery("sex","male"));
//        searchBuilder.query(boolQueryBuilder);


        //范围查询
        //构建范围请求体，填入要排序的字段
//        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
//        rangeQuery.gte(1);
//        rangeQuery.lte(3);
//        searchBuilder.query(rangeQuery);

        //模糊查询
//        searchBuilder.query(QueryBuilders.fuzzyQuery("name","xiang").fuzziness(Fuzziness.TWO));

        //高亮查询
//        TermQueryBuilder t = QueryBuilders.termQuery("name", "zhangsan");
//        searchBuilder.query(t);
//        HighlightBuilder high = new HighlightBuilder();
//        high.preTags("<font color='red'>");
//        high.field("name");
//        high.postTags("</font>");
//        searchBuilder.highlighter(high);

        //聚合查询
//        searchBuilder.aggregation(AggregationBuilders.max("age").field("age"));


        //分组查询
//        searchBuilder.aggregation(AggregationBuilders.terms("sex").field("sex"));


        //将查询请求体放入搜索对象中
        search.source(searchBuilder);
        SearchResponse hits = rest.search(search, RequestOptions.DEFAULT);

        SearchHits h = hits.getHits();
        for (SearchHit s : h) {
            System.out.println(s.getSourceAsString());
        }


        rest.close();
    }
    @After
    public void Destroy() throws IOException {
        rest.close();
    }

    public static SearchRequest getScRequest(){
        return new SearchRequest().indices("user");
    }

    @Test
    public void 查询所有文档() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.query(QueryBuilders.matchAllQuery());
        sc.source(scb);
        SearchResponse search = rest.search(sc, RequestOptions.DEFAULT);
        System.out.println(search);
    }

    @Test
    public void term条件查询() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.query(QueryBuilders.termQuery("name","zhangsan"));
        sc.source(scb);
        SearchResponse search = rest.search(sc, RequestOptions.DEFAULT);
        System.out.println(search);
    }

    @Test
    public void 分页() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.query(QueryBuilders.matchAllQuery());
        scb.size(2);
        scb.from(0);
        sc.source(scb);
        System.out.println(rest.search(sc, RequestOptions.DEFAULT));
    }

    @Test
    public void 排序() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.sort("age",SortOrder.DESC);
        sc.source(scb);
        System.out.println(rest.search(sc,RequestOptions.DEFAULT));
    }

    @Test
    public void 过滤字段() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        String[] excludes = {};
        String[] includes = {"name","age"};
        scb.fetchSource(includes,excludes);
        sc.source(scb);
        System.out.println(rest.search(sc,RequestOptions.DEFAULT));
    }

    @Test
    public void bool查询() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        BoolQueryBuilder bool = QueryBuilders.boolQuery();
        bool.must(QueryBuilders.matchQuery("name","zhangsan"));
        scb.query(bool);
        sc.source(scb);
        System.out.println(rest.search(sc,RequestOptions.DEFAULT));
    }

    @Test
    public void 范围查找() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        RangeQueryBuilder age = QueryBuilders.rangeQuery("age");
        age.gte(0);
        age.lte(3);
        scb.query(age);
        sc.source(scb);
        System.out.println(rest.search(sc, RequestOptions.DEFAULT));
    }

    @Test
    public void 模糊查询() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.query(QueryBuilders.fuzzyQuery("name","zhangsan"));
        sc.source(scb);
        System.out.println(rest.search(sc, RequestOptions.DEFAULT));
    }

    @Test
    public void 高亮查询() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.query(QueryBuilders.termQuery("name","zhangsan"));


        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.postTags("</font>");
        highlightBuilder.preTags("</font color='red'>");
        highlightBuilder.field("name");

        scb.highlighter(highlightBuilder);

        sc.source(scb);
        System.out.println(rest.search(sc, RequestOptions.DEFAULT));
    }

    @Test
    public void 聚合查询() throws IOException {

        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.aggregation(AggregationBuilders.max("1").field("age"));
        sc.source(scb);
        System.out.println(rest.search(sc, RequestOptions.DEFAULT));
    }

    @Test
    public void 分组查询() throws IOException {
        SearchRequest sc = getScRequest();
        SearchSourceBuilder scb = new SearchSourceBuilder();
        scb.aggregation(AggregationBuilders.terms("name").field("name"));
        sc.source(scb);
        System.out.println(rest.search(sc, RequestOptions.DEFAULT));
    }


}
